package com.dzirtbry.ticatac.UI;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

import com.dzirtbry.ticatac.game.GameModel;
import com.dzirtbry.ticatac.game.GameModelListner;
import com.dzirtbry.ticatac.game.GameSettings;
import com.dzirtbry.ticatac.pane.TicTacMarker;
import com.dzirtbry.ticatac.pane.TicTacPane;

@SuppressWarnings("serial")
public class TicTacWidget extends JPanel implements MouseListener, GameModelListner{
	private GameModel model;
	
	public TicTacWidget(GameModel model) {
		super();
		this.setModel(model);
		this.addMouseListener(this);
	}
	
	public int getColumnWidth() {
		return this.getWidth()/3;
	}
	
	public int getRowHeight() {
		return this.getHeight()/3;
	}
	
	public void setModel (GameModel model) {
		this.model = model;
		model.addListner(this);
	}
	
	@Override
	public void paintComponent (Graphics g) {
		super.paintComponent(g);
		drawGrid(g);
		TicTacPane pane = model.getPane();
		drawPane(g, pane);
	}
	
	private void drawPane (Graphics g, TicTacPane pane) {
		for (int i=0; i<3; i++) {
			for (int j=0; j<3; j++) {
				switch (pane.get(i, j)) {
				case TicTacMarker.TIC:
					drawX(g, i, j);
					break;
				case TicTacMarker.TAC:
					drawO(g, i, j);
					break;
				default:
					break;
				}
			}
		}
	}
	
	public void newGame() {
		model.removeListner(this);
		setModel(new GameModel(GameSettings.getInstance().getUser1(), GameSettings.getInstance().getUser2()));
		repaint();
	}
	
	private void drawGrid(Graphics g) {
		Dimension dimension = this.getSize();
		int colWidth = dimension.width / 3;
		int rowHeight= dimension.height / 3;
		g.drawLine(colWidth, 0, colWidth, dimension.height);
		g.drawLine(colWidth*2, 0, colWidth*2, dimension.height);
		g.drawLine(0, rowHeight, dimension.width, rowHeight);
		g.drawLine(0, rowHeight*2, dimension.width, rowHeight*2);
		
	}
	
	private void drawX(Graphics g, int x, int y) {
		drawSymbol(g, x, y, TicTacMarker.TIC);
	}
	
	private void drawO(Graphics g, int x, int y) {
		drawSymbol(g, x, y, TicTacMarker.TAC);
	}

	private void drawSymbol (Graphics g, int x, int y, int marker) {
		Dimension dimension = this.getSize();
		int colWidth = dimension.width / 3;
		int rowHeight = dimension.height / 3;
		
		switch (marker) {
		case 1:
			g.drawLine((int) (colWidth*(y+0.1)), (int) (rowHeight*(x+0.1)),
					(int) (colWidth*(y + 0.9)), (int) (rowHeight*(x + 0.9)));
			g.drawLine((int)(colWidth*(y+0.9)), (int) (rowHeight*(x+0.1)),
					(int)(colWidth*(y+0.1)), (int)(rowHeight*(x + 0.9)));
			break;
		case 2:
			g.drawOval((int)(colWidth*(y+0.1)), (int)(rowHeight*(x+0.1)), (int)(colWidth*0.80), (int)(rowHeight*0.80));
			break;
		}
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		if (e.getButton() == MouseEvent.BUTTON3) {
			newGame();
			return;
		}
		if ((e.getButton() == MouseEvent.BUTTON1) && (model.isFinished())) {
			JOptionPane.showMessageDialog(this, "Game over, right click to start new game");
			return;
		}
		int x = e.getX();
		int y = e.getY();
		System.out.println("Coords:" + String.format("%4d, %4d", x, y));
		int i = x / getColumnWidth();
		int j = y / getRowHeight();
		System.out.println("Pane coords:" + String.format("%2d, %2d", j, i));
		model.move(new Point(j, i));
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void paneChanged() {
		this.repaint();
	}

	@Override
	public void gameOver(int winner) {
		String text = "Game Over! ";
		switch (winner) {
		case TicTacMarker.TIC:
			text += "X won!";
			break;
		case TicTacMarker.TAC:
			text += "O won!";
			break;
		default:
			text += "Nobody won.";
			break;
		}
		JOptionPane.showMessageDialog(this, text);
	}
}
